/*
 * @Author: WangGuojian 1085844536@qq.com
 * @Date: 2023-04-04 22:51:03
 * @LastEditTime: 2023-04-05 00:45:58
 * @LastEditors: WangGuojian 1085844536@qq.com
 * @FilePath: \webpack\react-cli\config\webpack.dev.js
 * @Description:
 */
const EsLintWebpackPlugin = require('eslint-webpack-plugin');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

/**
 * 返回处理样式 loader
 */
const getStyleLoaders = (pre) => {
    return [
        'style-loader',
        'css-loader',
        {
            // 处理 css 兼容性问题
            // 配合 package.json 中的 browserslist 来指定兼容性
            loader: 'postcss-loader',
            options: {
                postcssOptions: {
                    plugins: ['postcss-preset-env'],
                },
            },
        },
        pre,
    ].filter(Boolean);
};

module.exports = {
    entry: './src/main.js',
    output: {
        path: undefined,
        filename: 'static/js/[name].js',
        chunkFilename: 'static/js/[name].chunk.js',
        assetModuleFilename: 'static/media/[hash:10][ext][query]',
    },
    module: {
        rules: [
            // 处理 css
            {
                test: /\.css$/,
                use: getStyleLoaders(),
            },
            {
                test: /\.less$/,
                use: getStyleLoaders('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader'),
            },
            // 处理图片
            {
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024,
                    },
                },
            },
            // 处理其他资源
            {
                test: /\.(woff2?|ttf)$/,
                type: 'asset/resource',
            },
            // 处理 js
            {
                test: /\.jsx?$/,
                include: path.resolve(__dirname, '../src'),
                loader: 'babel-loader',
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                    plugins: [
                        'react-refresh/babel', // 激活 js HMR
                    ],
                },
            },
        ],
    },
    // 处理html
    plugins: [
        new EsLintWebpackPlugin({
            context: path.resolve(__dirname, '../src'),
            exclude: 'node_modules',
            cache: true,
            cacheLocation: path.resolve(
                __dirname,
                '../node_modules/.cache/.eslintcache'
            ),
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html'),
        }),
        new ReactRefreshWebpackPlugin(), // 激活 js HMR
    ],
    mode: 'development',
    devtool: 'cheap-module-source-map',
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
        runtimeChunk: { name: (entrypoint) => `runtime~${entrypoint.name}.js` },
    },
    // webpack 解析模块加载选项
    resolve: {
        // 自动补全文件扩展名
        extensions: ['.jsx', '.js', '.json'],
    },
    devServer: {
        host: 'localhost',
        port: 3000,
        open: true,
        hot: true, // 开启 HMR
        historyApiFallback: true, // 解决前端路由刷新404问题
    },
};
